package com.topisv.tms.service.edi.lead;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.Area;
import com.topisv.tms.entity.CustomerAreaGroup;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.CustomersOrdenoSource;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.repository.CusStockMergeDao;
import com.topisv.tms.repository.CustomerAreaGroupDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.CustomersOrdenoSourceDao;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.ShopSourceDao;
import com.topisv.tms.service.AreaService;
import com.topisv.tms.service.EdiOrderService;
import com.topisv.tms.utils.lead.LeadUtil;
import com.topisv.tms.utils.rule.CreateOrdeno;
import com.topisv.tms.utils.rule.TMSRule;

@Component
@Transactional(readOnly = true)
public class LeadService {
	protected static Logger logger = LoggerFactory.getLogger(LeadService.class);
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private AreaService areaService;
	@Autowired
	private TMSRule tmsRule;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private CustomerAreaGroupDao customerAreaGroupDao;
	@Autowired
	private ShopSourceDao shopSourceDao;
	@Autowired
	private CustomersOrdenoSourceDao customersOrdenoSourceDao;
	@Autowired
	private CusStockMergeDao cusStockMergeDao;
	@Autowired
	private EdiOrderService ediOrderService;
	 
	
	private Map<Integer, Area> getAreas(List<Area> areas,String addres){
		Area temp=null;
		Integer index=0;
		Map<Integer, Area> maps=new HashMap<Integer, Area>();
		for(Area area:areas){
			StringBuffer sb=new StringBuffer("");
			char[] params=area.getAreaName().toCharArray();
			for(int i=0;i<params.length;i++){
				sb.append(params[i]);
				if(addres.startsWith(sb.toString())){
					if(i==params.length-1){
						if(i>index){
							index=params.length;
							temp=area;
						}
					}
				}else{
					if(i>index){
						index=i;
						temp=area;
					}
					break;
				}
			}
		}
		maps.put(index, temp);
		return maps;
	}
	
	public void getAreaProvoNew(EdiOrder ediOrder)throws Exception{
		try {
			List<Area> areas=areaService.findByAreaType("2");
			String address=ediOrder.getAddres().trim();
			boolean fa=false;
			Area area=null;
			Map<Integer, Area> maps=getAreas(areas,address);			
			for(Integer key:maps.keySet()){
				if(key<2){
					break;
				}
				area=maps.get(key);
				if(area!=null){
					ediOrder.setProvna(area.getAreaName());
					ediOrder.setProvco(area.getAreaCode());
					address=address.substring(key).trim();
					areas=areaService.findByAreaTypeAndArea(new String[]{"3","4"}, area);
					Map<Integer, Area> tempMaps=getAreas(areas,address);
					for(Integer k:tempMaps.keySet()){
						if(k<2){
							break;
						}
						Area a=tempMaps.get(k);
						if(a!=null){
							ediOrder.setCityco(a.getAreaCode());
							ediOrder.setCityna(a.getAreaName());
							address=address.trim().substring(key).trim();
							Map<Integer, Area> threedMaps=getAreas(areas,address);
							for(Integer kk:threedMaps.keySet()){
								if(kk<2){
									break;
								}
								  a=threedMaps.get(kk);
							      if(a!=null){
								    ediOrder.setDistco(a.getAreaCode());
								    ediOrder.setDistna(a.getAreaName());
							      }
							}
						}
					}
					fa=true;
				}
			}
			
			if(fa){
				ediOrder.setGymemo("1");
			}else{
				ediOrder.setGymemo("0");
			}
		} catch (Exception e) {
			logger.error("",e);
			throw e;
		}
	}

	private String getAreaType(String areaName, String areaType)
			throws Exception {
		try {
			Area area = areaService.getTopArea(areaName, areaType);
			if (area != null) {
				return area.getAreaCode();
			}
			return null;
		} catch (Exception e) {
			throw e;
		}
	}
	
	@Transactional(readOnly = false)
	public Map<String, List<EdiOrder>> saveHS(Collection<EdiOrder> ediOrders, String type) {
		    Map<String, List<EdiOrder>> mapEdiOrders=null;
		
			mapEdiOrders=new HashMap<String, List<EdiOrder>>();
			mapEdiOrders.put("exception", new ArrayList<EdiOrder>());//导入失败的订单
			mapEdiOrders.put("normal", new ArrayList<EdiOrder>());//导入成功的订单
			mapEdiOrders.put("suspect", new ArrayList<EdiOrder>());//疑似订单
			for (EdiOrder ediOrderOCR : ediOrders) {
				try {
					Customers customers=this.customersDao.findByCustomerCode(ediOrderOCR.getCustomerCode());
					if(customers==null){
						List<EdiOrder> exceptionEdiorders=mapEdiOrders.get("exception");
						exceptionEdiorders.add(ediOrderOCR);
						continue;
					}
					saveHS(ediOrderOCR, type, ediOrderOCR.getCustomerCode());	
					if("1".equals(ediOrderOCR.getGymemo())){
						List<EdiOrder> normalEdiorders=mapEdiOrders.get("normal");
						normalEdiorders.add(ediOrderOCR);
					}else if("0".equals(ediOrderOCR.getGymemo())){
						List<EdiOrder> suspectEdiorders=mapEdiOrders.get("suspect");
						suspectEdiorders.add(ediOrderOCR);
					}else{
						List<EdiOrder> exceptionEdiorders=mapEdiOrders.get("exception");
						exceptionEdiorders.add(ediOrderOCR);
					}
				} catch (Exception e) {
					List<EdiOrder> exceptionEdiorders=mapEdiOrders.get("exception");
					ediOrderOCR.setGymemo(e.getMessage());
					exceptionEdiorders.add(ediOrderOCR);
				}			
			}
		
		return mapEdiOrders;
	}

	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public Map<String, List<EdiOrder>> saveHS(Collection<EdiOrder> ediOrders, String type, String customerCode) {
		Map<String, List<EdiOrder>> mapEdiOrders=null;
		try {
			mapEdiOrders=new HashMap<String, List<EdiOrder>>();
			mapEdiOrders.put("exception", new ArrayList<EdiOrder>());//导入失败的订单
			mapEdiOrders.put("normal", new ArrayList<EdiOrder>());//导入成功的订单
			mapEdiOrders.put("suspect", new ArrayList<EdiOrder>());//疑似订单
			mapEdiOrders.put("repeat", new ArrayList<EdiOrder>());//重复订单
			Date nowDate=new Date();
			for (EdiOrder ediOrderOCR : ediOrders) {
				try {
					ediOrderOCR.setErpType(type);
					ediOrderOCR.setOrderStatus("ok");
					ediOrderOCR.setStatus("pending");
					ediOrderOCR.setAdtime(nowDate);
					ediOrderOCR.setPatime(nowDate);
					ediOrderOCR.setCrtime(nowDate);
					ediOrderOCR.setCustomerCode(customerCode);
					ediOrderOCR.setGymemo("1");
					if (!StringUtils.isBlank(ediOrderOCR.getShopna())) {
						ShopSource shopSource=this.shopSourceDao.findByShopName(ediOrderOCR.getShopna());
						if(shopSource!=null){
							ediOrderOCR.setShopCode(shopSource.getShopCode());
						}
					}
					
					//设置订单号
					try {
						List<EdiOrder> tempEdiOrders = ediOrderDao.findByCustomerCodeAndCustomerOrdenoAndOrderStatus(customerCode, ediOrderOCR.getCustomerOrdeno());
						EdiOrder tempEdiOrder = tempEdiOrders.isEmpty() ? null : tempEdiOrders.get(0);
						if (tempEdiOrder != null) {
							ediOrderOCR.setId(tempEdiOrder.getId());
							ediOrderOCR.setOrdeno(tempEdiOrder.getOrdeno());
							ediOrderOCR.setWaybillNo(tempEdiOrder.getWaybillNo());
							ediOrderOCR.setAdtime(tempEdiOrder.getAdtime());
							ediOrderOCR.setPatime(tempEdiOrder.getPatime());
							ediOrderOCR.setCrtime(tempEdiOrder.getCrtime());
							ediOrderOCR.setGymemo(tempEdiOrder.getGymemo());
							ediOrderOCR.setOrderStatus(tempEdiOrder.getOrderStatus());
							//ediOrderItemDao.deleteOrdeno(customerCode,ediOrderOCR.getOrdeno());
							List<EdiOrder> repeatEdiorders=mapEdiOrders.get("repeat");
							repeatEdiorders.add(ediOrderOCR);
							continue;
							/*if ("finish".equals(tempEdiOrder.getStatus())) {
								ediOrderOCR.setStatus("finish");
								ediOrderOCR.setBatchTaskCode(tempEdiOrder.getBatchTaskCode());
								ediOrderOCR.setBackupTaskCode(tempEdiOrder.getBackupTaskCode());
							}*/
						}else{
							if(ediOrderOCR.getWaybillNo()==null||"".equals(ediOrderOCR.getWaybillNo().trim())){
								try {
									ediOrderOCR.setWaybillNo(tmsRule.getNumber(customerCode));
								} catch (Exception e) {
									throw e;
								}
							}else{
								try {
									setWaybillNo(customerCode,ediOrderOCR);//设置能容运单号
								} catch (Exception e) {
								}
							}
							
							CreateOrdeno.setOrdenrOrdeno(ediOrderOCR, tmsRule);//能容订单号
						}
					} catch (Exception e) {
						logger.error("",e);
					}
					
					saveHS(ediOrderOCR, type, customerCode);	
					if("1".equals(ediOrderOCR.getGymemo())){
						List<EdiOrder> normalEdiorders=mapEdiOrders.get("normal");
						normalEdiorders.add(ediOrderOCR);
					}else{
						List<EdiOrder> suspectEdiorders=mapEdiOrders.get("suspect");
						suspectEdiorders.add(ediOrderOCR);
					}
				} catch (Exception e) {
					logger.error("error.",e);
					List<EdiOrder> exceptionEdiorders=mapEdiOrders.get("exception");
					ediOrderOCR.setGymemo(e.getMessage());
					exceptionEdiorders.add(ediOrderOCR);
				}			
			}
		} catch (Exception e) {
		}
		
		return mapEdiOrders;
	}
	

	public EdiOrder setAreaGroupCode(EdiOrder ediOrder)throws Exception {
		try {
			//设置网点
			List<CustomerAreaGroup> lists=this.customerAreaGroupDao.findByCustomerCodeOrderByLevelAsc(ediOrder.getCustomerCode());
			if(ediOrder.getProvco()!=null){
				for(CustomerAreaGroup list:lists){
					String areaLists=list.getAreaLists();
					if(areaLists!=null){
						if(areaLists.indexOf(ediOrder.getProvco())!=-1){
							if(null == ediOrder.getAreaGroupCode()){
								ediOrder.setAreaGroupCode(list.getAreaGroupCode());
							}
							break;
						}
					}
				}
			}else{
				ediOrder.setGymemo("0");
			}
			return ediOrder;
		} catch (Exception e) {
			throw e;
		}
	}

	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public EdiOrder saveHS(EdiOrder ediOrder, String type, String customerCode)throws Exception {
			try {
				
				String provCode =null;
				if(ediOrder.getProvna()==null){
					getAreaProvoNew(ediOrder);
				}else{
					if(ediOrder.getAddres().indexOf(ediOrder.getProvna())<0){
						ediOrder.setAddres(ediOrder.getProvna()+ediOrder.getCityna()+ediOrder.getDistna()+ediOrder.getAddres());
					}
					provCode = getAreaType(ediOrder.getProvna(), "2");
					if (provCode == null) {
						provCode = getAreaType(ediOrder.getCityna(), "3");
						if (provCode != null) {
							Area area = areaService.findByAreaCode(provCode);
							area = areaService.getArea(area.getArea().getId());
							if (area != null) {
								provCode = area.getAreaCode();
							}
						}
					}
					if (provCode == null) {
						ediOrder.setGymemo("0");
						provCode = "pending";
					}
					ediOrder.setProvco(provCode);// 设置省编码
				}
				setAreaGroupCode(ediOrder);
			} catch (Exception e) {
				ediOrder.setGymemo("0");
			}
		//保存订单
		try {
			return saveOrdenosHS(customerCode,ediOrder);
		} catch (Exception e) {
			throw e;
		}
	}
		
	
	/**
	 * 设置运单号
	 * @param customerCode
	 * @param ediOrder
	 * @throws Exception
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	private synchronized void setWaybillNo(String customerCode,EdiOrder ediOrder)throws Exception{
		try {
			// 得到最大运单号
			String maxWaybillNo = ediOrderDao.findMaxWaybillNo(customerCode);
			Customers customers = customersDao.findByCustomerCode(customerCode);
			String waybill=ediOrder.getWaybillNo();
			if(!(waybill==null||"".equals(waybill)||waybill.length()!=(customers.getStartNumber()+customers.getEndNumber()).length())){
				if (maxWaybillNo == null|| "".equals(maxWaybillNo)||is(waybill, maxWaybillNo)) {
					if(null!=ediOrder.getWaybillNo()){
						String waybillNo = ediOrder.getWaybillNo().substring(customers.getStartNumber().length());
						customers.setEndNumber(waybillNo);
						customersDao.save(customers);
					}
				}
			}else{
				ediOrder.setGymemo("0");
			}
		} catch (Exception e) {
			throw e;
		}
	}
	

	
	private boolean is(String waybillNo, String maxWaybill) {
		if(waybillNo==null||"".equals(waybillNo)){
			return false;
		}
		if (Long.parseLong(maxWaybill) < Long.parseLong(waybillNo)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 更新方式保存订单
	 * @param customerCode
	 * @param ediOrder
	 * @throws Exception
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	private EdiOrder saveOrdenosHS(String customerCode,EdiOrder ediOrder) throws Exception {
			try {
				if(StringUtils.isBlank(ediOrder.getOrdeno())){
					throw new RuntimeException("能容订单号为空,订单号为:"+ediOrder.getCustomerOrdeno());
				}
				List<EdiOrderItem> ediOrderItems = ediOrder.getSkulst();
				if ((ediOrderItems != null)) {
					if (ediOrderItems.size() == 1) {
						EdiOrderItem ediOrderItem = ediOrderItems.get(0);
						if (ediOrderItem.getQty() > 1) {
							ediOrder.setOrderType("multiple");
						} else {
							ediOrder.setOrderType("single");
						}
					} else {
						ediOrder.setOrderType("multiple");
					}
					int qty = 0;
					List<String>  match = new ArrayList<String>();
					for (int j = 0; j < ediOrderItems.size(); j++) {
						EdiOrderItem ediOrderItem = ediOrderItems.get(j);
						if(ediOrderItem.getSku()==null){
							   if(ediOrderItem.getSpec()==null){
								   EdiGoodsSku ediGoodsSku=ediGoodsSkuDao.findByCustomerCodeAndBar(customerCode, ediOrderItem.getArticleNumber());
									if(ediGoodsSku==null){
										ediOrder.setGymemo("货号："+ediOrderItem.getArticleNumber()+"对应的SKU编码不存在。");
										return ediOrder;
									}else{
										ediOrderItem.setSku(ediGoodsSku.getSku());
									}
							   }else{
								   EdiGoodsSku ediGoodsSku=ediGoodsSkuDao.findByCustomerCodeAndSpec(customerCode, ediOrderItem.getSpec());
								   if(ediGoodsSku==null){
										ediOrder.setGymemo("规格编码："+ediOrderItem.getSpec()+"对应的SKU编码不存在。");
										return ediOrder;
									}else{
										ediOrderItem.setSku(ediGoodsSku.getSku());
									}
							   }
								
							
						}
						ediOrderItem.setCustomerCode(customerCode);
						ediOrderItem.setWaybillNo(ediOrder.getWaybillNo());
						ediOrderItem.setCrtime(new Date());
						String ordeno = ediOrder.getOrdeno();
						ediOrderItem.setOrdeno(ordeno);
						qty += ediOrderItem.getQty();
						if(!match.contains(ediOrderItem.getSku()))
						{
							match.add(ediOrderItem.getSku());
						}
					}
					ediOrder.setSkuMatch(match.size()==1 ? "1":"2");
					ediOrder.setSkuQty(qty);
					//ediOrderItemDao.save(ediOrderItems);// 保存订单明细
				}
				ediOrder.setWarehouseCode(ediOrder.getAreaGroupCode());
				
				//校验库存
				Customers customers=customersDao.findByCustomerCode(ediOrder.getCustomerCode());
				//限制订单流入
				if ("1".equals(customers.getPlaceStatus())) {
					Map<String, Integer> maps = ediOrderService.setCusStock(ediOrder);
					if (maps == null) {
						//没有找到合适的库存
						throw new RuntimeException("库存不足,订单号为:"+ediOrder.getCustomerOrdeno());
					}
				}
				//合并订单
				//ediOrderService.margeOrdeno(ediOrder);
				Date nowDate = new Date();
				List<EdiOrderItem> orderItems = ediOrder.getSkulst();
				ediOrder.setOrderItems(orderItems);
				ediOrderService.mergeCusStock(ediOrder, ediOrder.getWarehouseCode(), true);
				for (EdiOrderItem ei : orderItems) {
					ei.setCrtime(nowDate);
					ei.setWaybillNo(ediOrder.getWaybillNo());
					ei.setCustomerCode(ediOrder.getCustomerCode());
					ediOrderItemDao.save(ei);
				}
				
				ediOrder.setGymemo("1");
				ediOrder.setAddres(ediOrder.getAddres().replace(" ", ""));
				ediOrderDao.save(ediOrder);// 保存订单状态
				return ediOrder;
			} catch (Exception e) {
				throw e;
			}
		}
	/**
	 * 根据合单条件，将导入的订单合并
	 * @param orders
	 * @return
	 * @throws Exception List<EdiOrder>
	 */
	public List<EdiOrder> mergeOrder(Collection<EdiOrder> orders,String customerCode, String type) throws Exception {
		List<EdiOrder> rs = new ArrayList<EdiOrder>();
		Map<String, List<EdiOrder>> rsMap = new HashMap<String, List<EdiOrder>>();
		for (EdiOrder ediOrder : orders) {
			List<CustomersOrdenoSource> customersOrdenoSources = customersOrdenoSourceDao.findByCustomerCode(customerCode);
			boolean flag = false;
			for (CustomersOrdenoSource cos : customersOrdenoSources) {
				if (cos.getShopCodes().indexOf(type) > -1) {
					flag = true;
					LeadUtil.groupOrder(rsMap, ediOrder, cos);
					break;
				}
			}
			if(!flag){
				rs.add(ediOrder);
			}
		}
		rs.addAll(LeadUtil.mergeOrder(rsMap));
		return rs;
	}
}
